#include "EditorNodeRotationPropertyModel.h"

#include "Object/NewObject.h"
#include "Scene/SceneNode.h"

TSharedObjectPtr<REditorNodeRotationPropertyModel> REditorNodeRotationPropertyModel::Create(
    TSharedObjectPtr<RSceneNode> InNode,
    RObject* InParent
    )
{
    TSharedObjectPtr<REditorNodeRotationPropertyModel> NewModel = NewObject<REditorNodeRotationPropertyModel>(InParent);
    NewModel->Node = InNode;

    return NewModel;
}

float REditorNodeRotationPropertyModel::GetX() const
{
    return Node->GetEulerAngleInDegree().X;
}

void REditorNodeRotationPropertyModel::SetX(float InX)
{
    SVec3 NewRotation = Node->GetEulerAngleInDegree();
    NewRotation.X = InX;
    Node->SetEulerAngleInDegree(NewRotation);
}

float REditorNodeRotationPropertyModel::GetY() const
{
    return Node->GetEulerAngleInDegree().Y;
}

void REditorNodeRotationPropertyModel::SetY(float InY)
{
    SVec3 NewRotation = Node->GetEulerAngleInDegree();
    NewRotation.Y = InY;
    Node->SetEulerAngleInDegree(NewRotation);
}

float REditorNodeRotationPropertyModel::GetZ() const
{
    return Node->GetEulerAngleInDegree().Z;
}

void REditorNodeRotationPropertyModel::SetZ(float InZ)
{
    SVec3 NewRotation = Node->GetEulerAngleInDegree();
    NewRotation.Z = InZ;
    Node->SetEulerAngleInDegree(NewRotation);
}

void REditorNodeRotationPropertyOperation::ChangeValue(TSharedObjectPtr<RSceneNode> InNode, const SVec3 &InOldValue, const SVec3 &InNewValue)
{
    Node = InNode;
    OldValue = InOldValue;
    NewValue = InNewValue;

    RedoFunction.Bind([this](TSharedObjectPtr<REditorPageModel>)
    {
        Node->SetEulerAngleInDegree(NewValue);
    });

    UndoFunction.Bind([this](TSharedObjectPtr<REditorPageModel> )
    {
        Node->SetEulerAngleInDegree(OldValue);
    });

    MergeFunction.Bind([this](TSharedObjectPtr<REditorPageOperation> Operation)
    {
        if(!Operation->IsA<REditorNodeRotationPropertyOperation>())
        {
            return false;
        }
        TSharedObjectPtr<REditorNodeRotationPropertyOperation> 
            FormerOperation=Operation;
        
        if(FormerOperation->Node!=Node
           )
        {
            return false;
        }

        if(FormerOperation->OldValue==NewValue)
        {
            return false;
        }

        FormerOperation->NewValue=NewValue;
        return true;

    });
    
}
